/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-08-18     SY       the first version
 */
#include "rtthread.h"
#include "gd32f10x_fmc.h"

#define FMC_WRITE_START_ADDR    0x08004000
#define FMC_WRITE_END_ADDR      0x08004800

int fmc_erase_pages(uint32_t start_addr,uint32_t size_byte)
{
    int ret=0;
    if(size_byte<=0)
    {
        return -1;
    }
    /* unlock the flash program/erase controller */
    fmc_unlock();
    /* clear all pending flags */

    /* erase the flash pages */
    int size=size_byte/2048;
    if(size==0)
    {
        size=1;
    }
    uint32_t addr=start_addr;
    for (int i = 0;i < size;i++)
    {
        fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR);
        if(fmc_page_erase(addr)!=FMC_READY)
        {
            ret=-2;
            break;
        }
        addr+=2048U;
        fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR);
    }

    /* lock the main FMC after the erase operation */
    fmc_lock();
    return ret;
}

int fmc_program(uint32_t start_addr,void *data,uint32_t data_len)
{
    int ret=0;
    if(data==NULL||data_len<=0)
    {
        return -1;
    }
    uint32_t *mdata=(uint32_t*)data;
    /* unlock the flash program/erase controller */
    fmc_unlock();

    int size=data_len;
    uint32_t address = start_addr;
    /* program flash */
    while(address <= (start_addr+data_len))
    {
        if(size <= 0)
        {
            break;
        }
        if(fmc_word_program(address, *mdata)!=FMC_READY)
        {
            ret=-2;
            fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR);
            break;
        }
        address += 4U;
        mdata++;
        fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR);
        size-=4;
    }
    /* lock the main FMC after the program operation */
    fmc_lock();

    return ret;
}
